package com.xltt.vehicleControl.util;


import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import com.xltt.vehicleControl.base.MyApplication;
import com.xltt.vehicleControl.bean.ReposFactory;
import com.xltt.vehicleControl.bean.TcVehicleProfile;
import com.xltt.vehicleControl.bean.UserResponse;
import com.xltt.vehicleControl.bean.XChangeConstant;
import com.xltt.vehicleControl.contants.Constants;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static com.xltt.vehicleControl.bean.Capability.checkString;


/**
 * Retrofit单例工具类
 * created by xucanyou666
 * on 2020/1/16 16:38
 * email：913710642@qq.com
 */
public class RetrofitManager {
    private Retrofit mRetrofit;

    /**
     * 构造器私有，这个工具类只有一个实例
     */
    private RetrofitManager() {
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(15, TimeUnit.SECONDS);
        httpClientBuilder.addInterceptor(builderRequestHeads2());//请求头
        httpClientBuilder.addInterceptor(builderHttpLoggingInterceptor());//请求日志
        //httpClientBuilder.addInterceptor(new LoggingInterceptorUtils());//请求日志
        httpClientBuilder.build();

        mRetrofit = new Retrofit.Builder()
                .client(httpClientBuilder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(Constants.getHost())
                .build();
    }

    /**
     * 构建日志输出过滤器
     *
     * @return
     */
    private HttpLoggingInterceptor builderHttpLoggingInterceptor() {
        //日志显示级别
        HttpLoggingInterceptor.Level level = HttpLoggingInterceptor.Level.BODY;
        //新建log拦截器
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Logger.d("Http Retrofit : " + message);
            }
        });
        loggingInterceptor.setLevel(level);
        return loggingInterceptor;
    }

    /**
     * 构建http请求头
     *
     * @return
     */
    private Interceptor builderRequestHeads() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                String accessToken = "";
                String clientId = "";
                UserResponse accountInfo = ReposFactory.getInstance().getUserResponse();
                if (accountInfo != null && checkString(accountInfo.getAccessToken())) {
                    accessToken = accountInfo.getAccessToken();
                }
                // 第二次添加 by add zhanghui@2021/3/9 + {
                if(accountInfo != null && checkString(accountInfo.getClientId())){
                    clientId = accountInfo.getClientId();
                }
                //第二次添加 by add zhanghui@2021/3/9 + }

                //登录注册接口不传入clientId Authorization
                boolean isLogin = request.url().toString().contains("login");
                boolean isRegister = request.url().toString().endsWith("/api/v1/user");
                if (isLogin || isRegister) {
                    accessToken = "";
                    clientId = "";
                }
                //v2修改车辆使用状态和获取能力集header里面不加车辆vin和车型
                boolean isHadBindCar = !request.url().toString().contains("/geelyTCAccess/tcservices/capability/")
                        && !request.url().toString().contains("/user/session/update");


                Request.Builder requestBuilder = request.newBuilder();
                if (request.header("Content-Type") == null
                        || request.header("Content-Type").trim().length() <= 0
                        || request.header("Content-Type").equals("")) {
                    requestBuilder.addHeader("Content-Type", "application/json; charset=utf-8");

                }
                TcVehicleProfile tcVehicleProfile = ReposFactory.getInstance().getTcVehicleProfile();
                if (tcVehicleProfile != null && isHadBindCar) {
                    requestBuilder.addHeader("X-VEHICLE-MODEL", getValueEncoded(tcVehicleProfile.getModelCode()));
                    requestBuilder.addHeader("X-Vehicle-IDENTIFIER", tcVehicleProfile.getVin());
                }
                requestBuilder
                        .addHeader("X-OPERATOR-CODE", XChangeConstant.X_OPERATOR_CODE)
                        .addHeader("X-APP-ID", XChangeConstant.getAppId())
                        .addHeader("Accept-Language", XChangeConstant.getNowLanguageType())
                        .addHeader("Accept", XChangeConstant.ACCEPT)
                        .addHeader("X-CLIENT-ID", clientId)
                        .addHeader("X-DEVICE-TYPE", XChangeConstant.getDeviceType())
                        .addHeader("X-ENV-TYPE", XChangeConstant.getNowEnvType())
                        .addHeader("Accept-Encoding", "identity")
                         // 第二次添加 by add zhanghui@2021/3/9 + {
                        .addHeader("X-STORE","FLOW")
                        .addHeader("X-DEVICE-IDENTIFIER", "bbce42a9-fed3-3cf1-82f0-cdeb2367a150")
                        .addHeader("SHA1", getSHA1(mContext))
                        .addHeader("x-agent-type", "android")
                        .addHeader("PROJECT_NAME", mContext.getPackageName());
                        //第二次添加 by add zhanghui@2021/3/9 + }

                if (checkString(accessToken)) {
                    requestBuilder = requestBuilder.addHeader("Authorization", accessToken);
                }
                Request request2 = requestBuilder.build();
                return chain.proceed(request2);
            }
        };
    }

    /**
     * 静态内部类单例模式
     *
     * @return
     */
    public static RetrofitManager getInstance() {
        return Inner.retrofitManager;
    }

    private static Context mContext;
    public void initContext(Context context){
        this.mContext = context;
    }

    private static class Inner {
        private static final RetrofitManager retrofitManager = new RetrofitManager();
    }


    /**
     * 利用泛型传入接口class返回接口实例
     *
     * @param ser 类
     * @param <T> 类的类型
     * @return Observable
     */
    public <T> T createRs(Class<T> ser) {
        return mRetrofit.create(ser);
    }

    private static String getValueEncoded(String value) {
        if (value == null) return "null";
        String newValue = value.replace("\n", "");
        for (int i = 0, length = newValue.length(); i < length; i++) {
            char c = newValue.charAt(i);
            if (c <= '\u001f' || c >= '\u007f') {
                try {
                    return URLEncoder.encode(newValue, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    return "";
                }
            }
        }
        return newValue;
    }



    private static String getSHA1(Context context){
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), PackageManager.GET_SIGNATURES);
            byte[] cert = info.signatures[0].toByteArray();
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] publicKey = md.digest(cert);
            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < publicKey.length; i++) {
                String appendString = Integer.toHexString(0xFF & publicKey[i])
                        .toUpperCase(Locale.US);
                if (appendString.length() == 1)
                    hexString.append("0");
                hexString.append(appendString);
                hexString.append(":");
            }
            String result = hexString.toString();
            return result.substring(0, result.length() - 1);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }


    /**
     * 正式版本请求头
     * @return
     */
    public static Map<String,String>  buildHeader(Request request){
        UserResponse accountInfo = ReposFactory.getInstance().getUserResponse();
        String clientId = "";
        if(accountInfo != null && checkString(accountInfo.getClientId())){
            clientId = accountInfo.getClientId();
        }else{
            clientId = ((MyApplication)mContext.getApplicationContext()).getAliDeviceId();
        }
        String accToken = "";
        if (accountInfo != null && checkString(accountInfo.getAccessToken())) {
            accToken = accountInfo.getAccessToken();
        }

        Map<String, String> heahers = new HashMap<>();
        heahers.put("X-APP-ID", Constants.APPID);
        heahers.put("Accept-Language", "en_US");
        heahers.put("Accept", "application/json;responseformat=3");
        heahers.put("Authorization",accToken);

        Request.Builder requestBuilder = request.newBuilder();
        if (request.header("Content-Type") == null
                || request.header("Content-Type").trim().length() <= 0
                || request.header("Content-Type").equals("")) {
            heahers.put("Content-Type", "application/json; charset=utf-8");
        }

        //heahers.put("Content-Type", "application/json; charset=utf-8");
        /** 客户端唯一标识（即IHU ID） */
        heahers.put("X-CLIENT-ID", clientId);
//        if(loginResponse!=null){
//            heahers.put("Authorization", EcarxNetImpl.getInstance().getCurrentUser().getAccessToken());
//        }
        /** 设备类型 */
        heahers.put("X-DEVICE-TYPE", "mobile");
        /** 商城类型 */
//        heahers.put("X-STORE","FLOW"); 张波提出取消
        /** 服务器环境的类型，开发、测试、生产"development", "testing", "staging", "production" 必填 */
        heahers.put("X-ENV-TYPE", "production");

        heahers.put("X-OPERATOR-CODE", "PROTON");
        /** 唯一标识（不采用imei的原因：6.0后用户可以拒绝READ_PHONE_STATE权限，无权限则无法获取imei，
         * 因此值为必传项，所以imei就不符合当前的使用场景） */
        //heahers.put("X-DEVICE-IDENTIFIER", "bbce42a9-fed3-3cf1-82f0-cdeb2367a150");
        heahers.put("X-DEVICE-IDENTIFIER", clientId);
        /** 配置x-agent-type  为android*/
        heahers.put("X-AGENT-TYPE", "android");
        heahers.put("SHA1", getSHA1(mContext));
        heahers.put("PROJECT_NAME", mContext.getPackageName());



        //张波提出添加 + {
        //v2修改车辆使用状态和获取能力集header里面不加车辆vin和车型
        boolean isHadBindCar = !request.url().toString().contains("/geelyTCAccess/tcservices/capability/")
                && !request.url().toString().contains("/user/session/update");
        TcVehicleProfile tcVehicleProfile = ReposFactory.getInstance().getTcVehicleProfile();
        if (tcVehicleProfile != null && isHadBindCar) {
            Logger.d("添加(X-VEHICLE-MODEL)请求头");
            heahers.put("X-VEHICLE-MODEL", getValueEncoded(tcVehicleProfile.getModelCode()));
            heahers.put("X-Vehicle-IDENTIFIER", tcVehicleProfile.getVin());
        }
        heahers.put("ECARX-NET-PLATFORM", "TSP");
        //张波提出添加 + }
        return  heahers;
    }

    private Interceptor builderRequestHeads2() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                Request.Builder requestBuilder = request.newBuilder();
                Map<String,String>  map = buildHeader(request);
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    //Logger.i(entry.getKey() + " ===== " + entry.getValue());
                    requestBuilder.addHeader(entry.getKey(),entry.getValue());
                }
                Request request2 = requestBuilder.build();
                return chain.proceed(request2);
            }
        };
    }
}
